package com.quectel.mobile.controller.partybuilding;

import cn.hutool.core.lang.func.LambdaUtil;
import com.quectel.constant.core.partybuilding.PartyBuildingMeetingConstants;
import com.quectel.constant.global.SystemConstants;
import com.quectel.core.module.partybuilding.dto.PartyPersonDto;
import com.quectel.core.module.partybuilding.service.PartyOrganizationService;
import com.quectel.core.module.partybuildingmeeting.dto.PartyBuildingMeetingDto;
import com.quectel.core.module.partybuildingmeeting.dto.PartyBuildingMeetingExperienceRecordDto;
import com.quectel.core.module.partybuildingmeeting.dto.PartyBuildingMeetingPersonBindingDto;
import com.quectel.core.module.partybuildingmeeting.service.PartyBuildingMeetingExperienceRecordService;
import com.quectel.core.module.partybuildingmeeting.service.PartyBuildingMeetingPersonBindingService;
import com.quectel.core.module.partybuildingmeeting.service.PartyBuildingMeetingService;
import com.quectel.mobile.controller.BaseController;
import com.quectel.mobile.util.SessionHolder;
import com.quectel.mobile.vo.partybuilding.PartyBuildingMeetingInfoResp;
import com.quectel.mobile.vo.partybuilding.PartyBuildingMeetingReq;
import com.quectel.mobile.vo.partybuilding.PartyBuildingMeetingResp;
import com.quectel.util.common.CopyUtils;
import com.quectel.util.common.Page;
import com.quectel.util.common.Request;
import com.quectel.util.common.Response;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * 在这里编写说明
 *
 * @author: bob
 * @email: bob.yu@quectel.com
 * @date: 2023-06-13 15:02:00
 */
@RestController
@RequestMapping("partyBuildingMeeting")
@Tag(name = "PartyBuildingMeetingController", description = "党建三会一课/主题党日/组织生活会相关api")
public class PartyBuildingMeetingController extends BaseController {

    @DubboReference
    private PartyBuildingMeetingService partyBuildingMeetingService;
    @DubboReference
    private PartyBuildingMeetingPersonBindingService meetingPersonBindingService;
    @DubboReference
    private PartyBuildingMeetingExperienceRecordService experienceRecordService;
    @DubboReference
    private PartyOrganizationService partyOrganizationService;

    @GetMapping("readExperience")
    @Operation(summary = "查看心得")
    public Response<Object> readExperience(  @Parameter(description = "meetingId") @RequestParam Long id){
        SessionHolder.checkPartyPerson();
        PartyPersonDto partyPerson = SessionHolder.getLoginMobileUserSession().getPartyPerson();

        PartyBuildingMeetingDto meetingDto = partyBuildingMeetingService.selectById(id);
        if (meetingDto!=null){
            PartyBuildingMeetingExperienceRecordDto experienceRecordDto = experienceRecordService.selectOne(meetingDto.getId(), partyPerson.getId());
            if (experienceRecordDto!=null){
                return Response.ok().wrap(experienceRecordDto);
            }else {
                return Response.error("未查询到心得记录");
            }
        }else {
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }
    }

    @PostMapping("makeExperience")
    @Operation(summary = "写心得")
    public Response<Object> makeExperience(@RequestBody @Validated PartyBuildingMeetingReq req){

        SessionHolder.checkPartyPerson();
        if (StringUtils.isEmpty(req.getTitle()) || StringUtils.isEmpty(req.getContent())){
            return Response.error("缺少必填参数");
        }
        PartyPersonDto partyPerson = SessionHolder.getLoginMobileUserSession().getPartyPerson();

        Date currentDate = new Date();
        PartyBuildingMeetingDto meetingDto = partyBuildingMeetingService.selectById(req.getId());
        if (meetingDto == null){
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }
        if (
           // 进行中
           (meetingDto.getStatus().equals(SystemConstants.YES) &&
                   meetingDto.getStartTime().before(currentDate) &&
                        meetingDto.getEndTime().after(currentDate)) ||
                   // 已结束
                   (meetingDto.getStatus().equals(SystemConstants.YES) &&  currentDate.after(meetingDto.getEndTime()))){

            PartyBuildingMeetingExperienceRecordDto experienceRecordDto =
                    experienceRecordService.selectOne(meetingDto.getId(), partyPerson.getId());

            if (experienceRecordDto == null){
                PartyBuildingMeetingExperienceRecordDto addly = new PartyBuildingMeetingExperienceRecordDto();
                addly.setPartyBuildingMeetingId(meetingDto.getId());
                addly.setPartyPersonId(partyPerson.getId());
                addly.setTitle(req.getTitle());
                addly.setContent(req.getContent());
                addly.setCreateTime(new Date());
                experienceRecordService.save(addly);
                return Response.ok();
            }else {
                return Response.error("您已提交过心得,无需重复提交");
            }
        }else {
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }
    }


    @PostMapping("sign")
    @Operation(summary = "签到")
    public Response<Object> sign(@RequestBody @Validated PartyBuildingMeetingReq req){

        SessionHolder.checkPartyPerson();
        PartyPersonDto partyPerson = SessionHolder.getLoginMobileUserSession().getPartyPerson();

        // 校验状态,status正常
        Map<String,Object> sqlMap = new HashMap<>();
        sqlMap.put(LambdaUtil.getFieldName(PartyBuildingMeetingDto::getStatus),
                PartyBuildingMeetingConstants.MeetingStatus.DOING.getStatus());
        sqlMap.put(LambdaUtil.getFieldName(PartyBuildingMeetingDto::getId),req.getId());

        int queryTotal = partyBuildingMeetingService.queryTotal(sqlMap);
        if (queryTotal == 0){
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }

        PartyBuildingMeetingPersonBindingDto meetingPersonBindingDto =
                meetingPersonBindingService.selectOne(req.getId(), partyPerson.getId());

        if (meetingPersonBindingDto.getSignStatus().equals(PartyBuildingMeetingConstants.SignStatus.SIGN.getStatus())){
             return Response.error("已签到,无需重复签到");
        }

        if (meetingPersonBindingDto.getSignStatus().equals(PartyBuildingMeetingConstants.SignStatus.NO_SIGN.getStatus())){

            PartyBuildingMeetingPersonBindingDto update = new PartyBuildingMeetingPersonBindingDto();
            update.setId(meetingPersonBindingDto.getId());
            update.setSignStatus(PartyBuildingMeetingConstants.SignStatus.SIGN.getStatus());
            update.setSignTime(new Date());
            meetingPersonBindingService.updateById(update);

        }

        return Response.ok();
    }

    @GetMapping("info/{id}")
    @Operation(summary = "根据id查询详情")
    public Response<PartyBuildingMeetingInfoResp> info(@PathVariable("id") Long id){
        SessionHolder.checkPartyPerson();
        PartyPersonDto partyPerson = Objects.requireNonNull(SessionHolder.getLoginMobileUserSession()).getPartyPerson();

        PartyBuildingMeetingDto meetingDto = partyBuildingMeetingService.selectById(id);
        if (meetingDto == null){
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }

        PartyBuildingMeetingInfoResp resp = CopyUtils.copyObj(meetingDto, PartyBuildingMeetingInfoResp.class);


        Map<String,Object> paramMap = new HashMap<>();
        paramMap.put(LambdaUtil.getFieldName(PartyBuildingMeetingExperienceRecordDto::getPartyBuildingMeetingId),meetingDto.getId());
        paramMap.put(LambdaUtil.getFieldName(PartyBuildingMeetingExperienceRecordDto::getPartyPersonId),partyPerson.getId());
        int experienceCount = experienceRecordService.queryTotal(paramMap);
        resp.setMeetingExperienceCount(experienceCount);

        PartyBuildingMeetingPersonBindingDto meetingPersonBindingDto = meetingPersonBindingService.selectOne(meetingDto.getId(), partyPerson.getId());
        if (meetingPersonBindingDto!=null && meetingPersonBindingDto.getSignStatus().equals(PartyBuildingMeetingConstants.SignStatus.SIGN.getStatus())){
            resp.setIsSign(SystemConstants.YES);
        }else {
            resp.setIsSign(SystemConstants.NO);
        }

        return Response.<PartyBuildingMeetingInfoResp>ok().wrap(resp);
    }

    /**
     * 全部：显示全部状态；待参加：未签到的进行中和未开始状态；已参加：签到过的所有状态；
     *
     *按钮：
     * 1、“去签到按钮”：进行中+未签到过的；
     *
     * 2、“写心得按钮”：签到过的；
     *
     * 3、“查看心得按钮”：提交过心得的；
     *
     * 4、“未签到按钮”：已结束+未签到；
     *
     * @param category
     * @param type
     * @param joinStatus
     * @param pageNo
     * @param pageSize
     * @return
     */
    @GetMapping("list")
    @Operation(summary = "党建三会一课/主题党日/组织生活会分页查询列表")
    public Response<Page<PartyBuildingMeetingResp>> list(
            @Parameter(description = "大分类 字典值PartyBuildingMeeting: 1三会一课 2主题党日 3组织生活会") @RequestParam Byte category,
            @Parameter(description = "大分类对应小分类") @RequestParam(required = false) Byte type,
            @Parameter(description = "参与状态 0待参与 1已参加") @RequestParam(required = false)Byte joinStatus,
            @Parameter(description = "从1开始的页码数") @RequestParam Integer pageNo,
            @Parameter(description = "每页多少条") @RequestParam Integer pageSize
    ) {
        SessionHolder.checkPartyPerson();
        PartyPersonDto partyPerson = SessionHolder.getLoginMobileUserSession().getPartyPerson();
        Request request = Request.configParams(Request.parseParams(httpServletRequest));

        request.getParams().put(LambdaUtil.getFieldName(PartyBuildingMeetingDto::getTenantId), partyPerson.getTenantId());
        request.getParams().put(PartyBuildingMeetingConstants.JOIN_STATUS , joinStatus);
        request.getParams().put(LambdaUtil.getFieldName(PartyBuildingMeetingPersonBindingDto::getPartyPersonId),partyPerson.getId());
        request.getParams().put(LambdaUtil.getFieldName(PartyBuildingMeetingDto::getCategory), category);
        request.getParams().put(LambdaUtil.getFieldName(PartyBuildingMeetingDto::getType), type);

        int totalCount = partyBuildingMeetingService.queryTotal(request.getParams());
        List<PartyBuildingMeetingResp> respList = new ArrayList<>();
        List<PartyBuildingMeetingDto> list = null;
        if (totalCount > 0) {
            list = partyBuildingMeetingService.queryListWithoutPadding(request.getParams());

            for (PartyBuildingMeetingDto meetingDto : list) {
                Map<String,Object> paramMap = new HashMap<>();
                paramMap.put(LambdaUtil.getFieldName(PartyBuildingMeetingExperienceRecordDto::getPartyBuildingMeetingId),meetingDto.getId());
                paramMap.put(LambdaUtil.getFieldName(PartyBuildingMeetingExperienceRecordDto::getPartyPersonId),partyPerson.getId());
                int experienceCount = experienceRecordService.queryTotal(paramMap);

                PartyBuildingMeetingResp resp = new PartyBuildingMeetingResp();
                resp.setId(meetingDto.getId());
                resp.setSubject(meetingDto.getSubject());
                resp.setAddress(meetingDto.getAddress());
                resp.setStartTime(meetingDto.getStartTime());
                resp.setEndTime(meetingDto.getEndTime());
                resp.setMeetingExperienceCount(experienceCount);
                resp.setStatus(meetingDto.getStatus());
                PartyBuildingMeetingPersonBindingDto meetingPersonBindingDto = meetingPersonBindingService.selectOne(meetingDto.getId(), partyPerson.getId());
                if (meetingPersonBindingDto.getSignStatus().equals(PartyBuildingMeetingConstants.SignStatus.SIGN.getStatus())){
                    resp.setIsSign(SystemConstants.YES);
                }else {
                    resp.setIsSign(SystemConstants.NO);
                }
                respList.add(resp);
            }
        }
        Page<PartyBuildingMeetingResp> page = new Page<>(request.getPageNo(), request.getPageSize(), totalCount, respList);
        return Response.<Page<PartyBuildingMeetingResp>>ok().wrap(page);
    }

}
